package com.hntky.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hntky.common.Result;
import com.hntky.entity.FileBean;
import com.hntky.mapper.FileMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;

/**
 * @author 周宇轩
 * @date 2023/5/8 14:37
 * 文件上传接口
 */

@RestController
@RequestMapping("/file")
public class FileController {

    @Value("${files.upload.path}")
    private String fileUploadPath;

    @Resource
    private FileMapper fileMapper;

    @PostMapping("/upload")
    public String upload(@RequestParam MultipartFile file) throws IOException {
        // 获取文件的全称
        String originalFilename = file.getOriginalFilename();
        // 获取文件的类型
        String type = FileUtil.extName(originalFilename);
        // 获取文件的大小
        long size = file.getSize();
        // 先存储到磁盘
        File uploadParentPath = new File(fileUploadPath);
        // 判断文件目录是否存在，不存在则新建
        if (!uploadParentPath.exists()) {
            uploadParentPath.mkdirs();
        }
        // 定义一个唯一文件标识
        String uuid = IdUtil.fastSimpleUUID();
        String fileUUID = uuid + StrUtil.DOT + type;
        File uploadFile = new File(fileUploadPath + fileUUID);
        // 把获取的文件放到磁盘目录
        file.transferTo(uploadFile);
        // 获取文件的md5
        String md5 = SecureUtil.md5(uploadFile);
        // 将文件上传到磁盘之前先去数据库查询是否有相同的文件
        FileBean fileOne = getFileByMd5(md5);
        String url;
        if (fileOne != null) {
            url = fileOne.getUrl();
            // 由于文件已存在，所以删除刚才上传的重复文件
            uploadFile.delete();
        } else {
            // 数据库若不重复文件，则不删除刚才上传的文件
            url = "http://localhost:8081/file/" + fileUUID;
        }
        // 存储数据库
        FileBean fileBean = new FileBean();
        fileBean.setName(originalFilename);
        fileBean.setType(type);
        fileBean.setSize(size / 1024);
        fileBean.setUrl(url);
        fileBean.setMd5(md5);
        fileMapper.insert(fileBean);
        return url;
    }

    /**
     * 文件下载
     * @param fileUUID
     * @param response
     * @throws IOException
     */
    @GetMapping("/{fileUUID}")
    public void download(@PathVariable String fileUUID, HttpServletResponse response) throws IOException {
        // 根据文件的唯一标识码获取文件
        File uploadFile = new File(fileUploadPath + fileUUID);
        // 设置输出流的格式
        ServletOutputStream os = response.getOutputStream();
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileUUID, "UTF-8"));
        response.setContentType("application/octet-stream");

        // 读取文件的字节流
        os.write(FileUtil.readBytes(uploadFile));
        os.flush();
        os.close();
    }

    /**
     * 分页查询接口
     * @param pageNum
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    public Result findPage(@RequestParam Integer pageNum,
                           @RequestParam Integer pageSize,
                           @RequestParam(defaultValue = "") String name) {

        QueryWrapper<FileBean> queryWrapper = new QueryWrapper<>();
        // 查询未删除的记录
        queryWrapper.eq("is_delete", false);
        if (!"".equals(name)) {
            queryWrapper.like("name", name);
        }
        return Result.success(fileMapper.selectPage(new Page<>(pageNum, pageSize), queryWrapper));
    }

    @DeleteMapping("/{id}")
    public Result delete(@PathVariable Integer id) {
        FileBean fileBean = fileMapper.selectById(id);
        fileBean.setIsDelete(true);
        fileMapper.updateById(fileBean);
        return Result.success();
    }

    @PostMapping("/del/batch")
    public Result deleteBatch(@RequestBody List<Integer> ids) {
        // select * from sys_file where id in (id,id,id...)
        QueryWrapper<FileBean> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", ids);
        List<FileBean> fileBeans = fileMapper.selectList(queryWrapper);
        for (FileBean fileBean : fileBeans) {
            fileBean.setIsDelete(true);
            fileMapper.updateById(fileBean);
        }
        return Result.success();
    }

    /**
     * 通过md5获取文件
     * @param md5
     * @return
     */
    private FileBean getFileByMd5(String md5) {
        QueryWrapper<FileBean> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("md5", md5);
        List<FileBean> fileLists = fileMapper.selectList(queryWrapper);
        return fileLists.size() == 0 ? null : fileLists.get(0);
    }

}
